# Create your views here.
import random
from google.appengine.ext.webapp import template

from django.conf import settings
from django.http import HttpResponse
from django.template.loader import render_to_string
from django.utils.translation import ugettext_lazy as _

from models import Draw, Player
from decorators import render_to
from forms import SorteoForm, PlayerForm, PlayerFormset
from appl_bij import ApplBij

from google.appengine.api.mail import send_mail
#from mailer import send_mail

def _correlation_matrix(players, exclusions):
    ''' players = [Player1, Player2,...]
        exclusions = {1:{3,4}, 2:{0,2}...}
        returns [[True,False,False...],[False,True,False,...]]
    '''
    corr = [[] for i in range(len(players))]
    for i in range(len(players)):
        excs = exclusions.get(i,[])
        for j in range(len(players)):
            if players[i].drawid==j: corr[j].append(False)
            elif j+1 in excs: corr[j].append(False)
            else: corr[j].append(True)

    return corr

@render_to('sorteo.html')
def sorteo(request):
    if request.method=='POST':
        form = SorteoForm(request.POST)
        formset = PlayerFormset(request.POST)
        if form.is_valid() and formset.is_valid():
            players = []
            
            exclusions = {}
            for player_form in formset.forms:
                email = player_form.cleaned_data['email']
                player = Player(name = player_form.cleaned_data['name'],
                                email = email,
                                domain = email[email.index('@')+1:],
                                pwd = _generate_random_code(4,False),
                                )
                player.drawid = int(player_form.cleaned_data['draw_id'])-1
                ids = player_form.cleaned_data['exclusion_ids']
                exclusions[player.drawid] = ids
                
                players.append(player)
               
             
            import operator
            players.sort(key=operator.attrgetter('drawid'))
            corr = _correlation_matrix(players, exclusions) 
            appl = ApplBij(corr, 'UNSAFE')
            loopSize = appl.GetLoopSize()
            result = appl.GetRandomApplBij(loopSize)

            draw = form.save(commit=False)
            draw.language = "es-es"
            draw.code = _generate_random_code()
            stats = appl.GetDrawStat()
            draw.matrix_size = stats[0]
            draw.mode = stats[1]
            draw.density = stats[2]
            draw.loop_size = stats[3]
            draw.loops = stats[4]
            draw.success = stats[5]
            draw.save()

            for player in players:
                player.draw = draw
                player.save()

            if not result:
                return HttpResponse(render_to_string('sorteo_result.html',
                                                     {'error':_('Solution NOT found')}),
                                                     mimetype='text/html')
                
            for i in range(len(result)):
                players[i].friend=players[result[i]]
                players[i].save()
            
            for player in players:
                subject, body, email = _create_mail(draw, player)
                send_mail(subject=subject, body=body, sender=settings.FROM_EMAIL, to=email)

            return HttpResponse(render_to_string('sorteo_result.html',{'code':draw.code, 'result':result, 'corr':corr}),mimetype='text/html')

    else:
        form = SorteoForm(initial={'subject':_('$NAME, your secret santa draw'),
                                   'body':_('You are to give a gift to $FRIEND')})
        formset = PlayerFormset()
        
    return {'draw_form':form, 'player_formset': formset}

def _create_mail(draw, player):
    subject = draw.subject
    body = draw.body
    
    keywords = {'$NOMBRE':player.name,'$NAME':player.name,
                '$AMIGO':player.friend.name,'$FRIEND':player.friend.name,
                'http':'xyz','www':'xyz','href':'xyz','javascript':'xyz','mailto':'xyz','onclick':'xyz'
                }
    
    for key,value in keywords.items():
        if key in subject:
            subject = subject.replace(key,value)
            
    for key,value in keywords.items():
        if key in body:
            body = body.replace(key,value)

    email = player.email
    
    return subject, body, email

def _generate_random_code(length=6, check_draw=True):
    a = '123456789ABCDEFGHIJKLMNPQRSTUVWXYZ'
    while True:
        code = ''
        for i in range(length):
            code += random.choice(a)
        if check_draw:
            if Draw.all().filter('code',code).count()==0:
                return code
        else:
            return code
